package cn.enilu.guns.admin.modular.door;

import cn.enilu.guns.admin.common.constant.device.TableConstant;
import cn.enilu.guns.admin.common.constant.enums.UpdateToDoorStatus;
import cn.enilu.guns.admin.core.base.tips.SetDataToDeviceTip;
import cn.enilu.guns.admin.core.base.tips.Tip;
import cn.enilu.guns.admin.equipment.dto.UserauthorizeDto;
import cn.enilu.guns.bean.entity.door.*;
import cn.enilu.guns.bean.entity.system.User;
import cn.enilu.guns.admin.equipment.service.EntranceGuardService;
import cn.enilu.guns.service.door.*;

import cn.enilu.guns.bean.annotion.core.BussinessLog;
import cn.enilu.guns.bean.constant.factory.PageFactory;
import cn.enilu.guns.bean.dictmap.CommonDict;
import cn.enilu.guns.admin.core.base.controller.BaseController;

import cn.enilu.guns.bean.vo.query.Page;
import cn.enilu.guns.bean.vo.query.SearchFilter;


import cn.enilu.guns.service.system.UserService;
import cn.enilu.guns.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.ui.Model;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/door/ENTRANCE/GUARD/RULE")
public class EntranceGuardRuleController extends BaseController {
	private  Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private DoorInfoService doorInfoService;
	@Autowired
	private EntranceGuardDoorService entranceGuardDoorService;
	@Autowired
	private EntranceGuardRuleService entranceGuardRuleService;
	@Autowired
	private TimeInfoService timeInfoService;
	@Autowired
	private EntranceGardUserService entranceGardUserService;
	@Autowired
	private EntranceGuardService entranceGuardService;
	@Autowired
	private UserService userService;
	private static String PREFIX = "/door/ENTRANCE/GUARD/RULE/";

	/**
	* 跳转到首页
	*/
	@RequestMapping(value="",method = RequestMethod.GET)
		public String index(Model model) {
        List<TimeInfo> timeInfoList = timeInfoService.queryAll();
        model.addAttribute("timeInfoList",timeInfoList);
		return PREFIX + "index.html";
	}

	/**
	* 跳转到添加页面
	*/
	@RequestMapping(value = "/add",method = RequestMethod.GET)
		public String add(Model model) {
		List<TimeInfo> timeInfoList = timeInfoService.queryAll();
		model.addAttribute("timeInfoList",timeInfoList);
		return PREFIX + "add.html";
	}

	/**
	* 跳转到修改页面
	*/
	@RequestMapping("/edit/{id}")
	public String edit(@PathVariable Long id, Model model) {
		EntranceGuardRule entity = entranceGuardRuleService.get(id);
		model.addAttribute("item",entity);
        List<TimeInfo> timeInfoList = timeInfoService.queryAll();
        model.addAttribute("timeInfoList",timeInfoList);
		return PREFIX + "edit.html";
	}
	@RequestMapping(value = "/list",method = RequestMethod.POST)
	@ResponseBody
	public Object list(@RequestParam(required = false) String ruleName,@RequestParam(required = false) String timeId) {
		Page<EntranceGuardRule> page = new PageFactory<EntranceGuardRule>().defaultPage();
		page.addFilter("ruleName", SearchFilter.Operator.EQ,ruleName);
		page.addFilter("timeInfo.id", SearchFilter.Operator.EQ,timeId);

		page = entranceGuardRuleService.queryPage(page);
		return super.packForBT(page);
	}

	/**
	 * 获取所有门禁权限
	 */
	@RequestMapping(value = "/getRuleList")
	@ResponseBody
	@BussinessLog(value = "获取所有门禁权限", key = "name",dict= CommonDict.class)
	public Object getRuleList(@RequestParam(required = false) Long id) {
		List<SearchFilter> searchFilters = Lists.newArrayList();
		List<EntranceGuardRule> entranceGuardRules = entranceGuardRuleService.queryAll(searchFilters, new Sort(Sort.Direction.ASC, "id"));
		return entranceGuardRules;
	}

	/**
	* 新增门禁权限
	*/
	@RequestMapping(value = "/add",method = RequestMethod.POST)
	@ResponseBody
	@BussinessLog(value = "新增门禁权限", key = "name",dict= CommonDict.class)
	public Object add(EntranceGuardRule entranceGuardRule) {
		entranceGuardRuleService.insert(entranceGuardRule);
		return SUCCESS_TIP;
	}

	/**
	* 删除门禁权限
	*/
	@RequestMapping(value = "/delete")
	@ResponseBody
	@BussinessLog(value = "删除门禁权限", key = "id",dict= CommonDict.class)
	public Object delete(@RequestParam Long id) {
		entranceGuardRuleService.delete(id);
		return SUCCESS_TIP;
	}

	/**
	* 修改门禁权限
	*/
	@RequestMapping(value = "/update")
	@ResponseBody
	@BussinessLog(value = "修改门禁权限", key = "name",dict= CommonDict.class)
	public Object update(EntranceGuardRule entranceGuardRule) {

		EntranceGuardRule entranceGuardRule1 = entranceGuardRuleService.get(entranceGuardRule.getId());
		entranceGuardRule1.setTimeInfo(entranceGuardRule.getTimeInfo());
		entranceGuardRuleService.update(entranceGuardRule1);
		entranceGuardRule = entranceGuardRuleService.get(entranceGuardRule.getId());
		//todo 根据权限获取时段信息,设置时段信息
		for (DoorInfo doorInfo:entranceGuardRule.getDoorInfos() ) {
			//清除时段
			entranceGuardService.cleanDeviceData(doorInfo.getEquipmentInfo().getIpAddress(),TableConstant.TABLE_TIMEZONE);
			entranceGuardService.addDataToDoor(doorInfo, TableConstant.TABLE_TIMEZONE, entranceGuardRule.getTimeInfo().toString());
		}
		return SUCCESS_TIP;
	}

	/**
	 * 跳转到分配人员页面
	 */
	@RequestMapping("/selectUserToRule/{id}")
	public String selectUserToRule(@PathVariable Long id, Model model) {
		EntranceGuardRule entity = entranceGuardRuleService.get(id);
		model.addAttribute("item",entity);
//		logger.info("------------------"+entity.getUsers().toString());
		return PREFIX + "selectUserToRule.html";
	}

    /**
     * 跳转到分配门页面
     */
    @RequestMapping("/selectDoorToRule/{id}")
    public String selectDoorToRule(@PathVariable Long id, Model model) {
        EntranceGuardRule entity = entranceGuardRuleService.get(id);
        model.addAttribute("item",entity);
//		logger.info("------------------"+entity.getUsers().toString());
        return PREFIX + "selectDoorToRule.html";
    }
	/**
	 * 跳转到权限详情页面
	 */
	@RequestMapping("/detail/{id}")
	public String detail(@PathVariable Long id, Model model) {
		EntranceGuardRule entity = entranceGuardRuleService.get(id);
		model.addAttribute("item",entity);
//		logger.info("------------------"+entity.getUsers().toString());
		return PREFIX + "detail.html";
	}
	/**
	 * 获取门禁权限已分配的人员
	 */
	@RequestMapping(value = "/selectUserForRule")
	@ResponseBody
	@BussinessLog(value = "获取门禁权限已分配的人员", key = "name",dict= CommonDict.class)
	public Object selectUserForRule(@RequestParam(required = false) Long id) {
		EntranceGuardRule entity = entranceGuardRuleService.get(id);
		return entity.getUsers();
	}
    /**
     * 获取门禁权限已分配的门
     */
    @RequestMapping(value = "/selectDoorForRule")
    @ResponseBody
    @BussinessLog(value = "获取门禁权限已分配的门", key = "name",dict= CommonDict.class)
    public Object selectDoorForRule(@RequestParam(required = false) Long id) {
        EntranceGuardRule entity = entranceGuardRuleService.get(id);
        return entity.getDoorInfos();
    }
	/**
	 * 角色分配
	 * @param entranceGuardRule
	 * @param idsArr
	 * @return
	 */
	@RequestMapping(value = "assignRule")
	@ResponseBody
	@BussinessLog(value = "门禁权限添加人员", key = "name",dict= CommonDict.class)
	public Object assignRule(EntranceGuardRule entranceGuardRule, String[] idsArr) {

		entranceGuardRule = entranceGuardRuleService.get(entranceGuardRule.getId());

		//生成已经存储的权限Map
		Map<String ,User> oldUserMap = new HashMap<>();
		for (User user:entranceGuardRule.getUsers()) {
			oldUserMap.put(entranceGuardRule.getId()+"_" + user.getId(),user);
		}
		//新添加的分配的人员
		List<User> addUsers = Lists.newArrayList();
        //需要删除的的人员
		List<User> removeUsers = Lists.newArrayList();
		//最新存储人员
		Map<String ,String> newUserMap = new HashMap<>();
		for (int i = 0; i < idsArr.length; i++) {
			//将未分配的人员写入权限关系中，并同步到设备中
			if(null == oldUserMap.get(entranceGuardRule.getId()+ "_" + idsArr[i])) {
				EntranceGardUser entranceGardUser = new EntranceGardUser();
				entranceGardUser.setRuleId(entranceGuardRule.getId());
				entranceGardUser.setUserId(Long.valueOf(idsArr[i]));
				entranceGardUser.setStaus(UpdateToDoorStatus.unUpdate.getValue());
				entranceGardUserService.insert(entranceGardUser);
				addUsers.add(userService.get(Long.valueOf(idsArr[i])));
			}
			newUserMap.put(entranceGuardRule.getId()+ "_" + idsArr[i],idsArr[i]);
		}

		for(Map.Entry<String, User> entry : oldUserMap.entrySet()){
			if(!newUserMap.containsKey(entry.getKey())) {
				//删除人员
				List<SearchFilter> searchFilters = Lists.newArrayList();
				searchFilters.add(new SearchFilter("ruleId",SearchFilter.Operator.EQ,entranceGuardRule.getId()));
				searchFilters.add(new SearchFilter("userId",SearchFilter.Operator.EQ,entry.getValue().getId()));
				List<EntranceGardUser> entranceGardUsers = entranceGardUserService.queryAll(searchFilters);
				for (EntranceGardUser entranceGardUser:entranceGardUsers) {
					entranceGardUserService.delete(entranceGardUser.getId());
				}
				removeUsers.add(entry.getValue());
			}
		}

//		EntranceGuardRule entity = entranceGuardRuleService.get(entranceGuardRule.getId());
		String strTip = "";
		for (DoorInfo doorInfo:entranceGuardRule.getDoorInfos() ) {
			//todo 根据权限获取时段信息,设置时段信息
			entranceGuardService.addDataToDoor(doorInfo, TableConstant.TABLE_TIMEZONE, entranceGuardRule.getTimeInfo().toString());

			//向设备中写入新增人员信息
			List<UserCard> addUserCards = entranceGardUserService.getUserAndCardInfoByUserList(addUsers);
			if(addUserCards.size()>0) {
				entranceGuardService.addDataToDoor(doorInfo, TableConstant.TABLE_USER, addUserCards);


				//向设备中写入权限信息
				List<UserauthorizeDto> userauthorizeDtos = Lists.newArrayList();
				for (UserCard userCard : addUserCards) {
					UserauthorizeDto userauthorizeDto = new UserauthorizeDto();
					userauthorizeDto.setUserId(userCard.getUserInfo().getId());
					//todo 添加时段信息
					userauthorizeDto.setTimeInfoId(entranceGuardRule.getTimeInfo().getId());
					userauthorizeDto.setDoorId(Long.valueOf(doorInfo.getDoorNo()));
					userauthorizeDtos.add(userauthorizeDto);
				}
				entranceGuardService.addDataToDoor(doorInfo, TableConstant.USERAUTHORIZE, userauthorizeDtos);
			}
			//向设备中写入需要删除的人员信息
			List<UserCard> removeUserCards = entranceGardUserService.getUserAndCardInfoByUserList(removeUsers);
			if(removeUserCards.size() > 0) {
				entranceGuardService.removeDataFromDoor(doorInfo, TableConstant.TABLE_USER, removeUserCards);
				//向设备中写入权限信息
				List<UserauthorizeDto> userauthorizeDtos = Lists.newArrayList();
				for (UserCard userCard : removeUserCards) {
					UserauthorizeDto userauthorizeDto = new UserauthorizeDto();
					userauthorizeDto.setUserId(userCard.getUserInfo().getId());
					//todo 添加时段信息
					userauthorizeDto.setTimeInfoId(entranceGuardRule.getTimeInfo().getId());
					userauthorizeDto.setDoorId(Long.valueOf(doorInfo.getDoorNo()));
					userauthorizeDtos.add(userauthorizeDto);
				}
				entranceGuardService.removeDataFromDoor(doorInfo, TableConstant.USERAUTHORIZE, userauthorizeDtos);
			}
		}

		SetDataToDeviceTip setDataToDeviceTip = new SetDataToDeviceTip(200,strTip);

		return setDataToDeviceTip;
	}
    /**
     * 门禁权限添加门
     * @param entranceGuardRule
     * @param idsArr
     * @return
     */
    @RequestMapping(value = "assignRuleToDoor")
    @ResponseBody
    @BussinessLog(value = "门禁权限添加门", key = "name",dict= CommonDict.class)
    public Object assignRuleToDoor(EntranceGuardRule entranceGuardRule, String[] idsArr) {
		entranceGuardRule = entranceGuardRuleService.get(entranceGuardRule.getId());

		//生成已经存储的门Map
		Map<String ,DoorInfo> oldDoorInfoMap = new HashMap<>();
		for (DoorInfo doorInfo:entranceGuardRule.getDoorInfos()) {
			oldDoorInfoMap.put(entranceGuardRule.getId()+"_" + doorInfo.getId(),doorInfo);
		}
		//新添加的分配的人员
		List<DoorInfo> addDoorInfos = Lists.newArrayList();
		//需要删除的的人员
		List<DoorInfo> removeDoorInfos = Lists.newArrayList();
		//最新存储人员
		Map<String ,String> newDoorInfoMap = new HashMap<>();
		for (int i = 0; i < idsArr.length; i++) {
			//将未分配的人员写入权限关系中，并同步到设备中
			if(null == oldDoorInfoMap.get(entranceGuardRule.getId()+ "_" + idsArr[i])) {
				DoorInfo doorInfo = doorInfoService.get(Long.valueOf(idsArr[i]));
				EntranceGuardDoor entranceGuardDoor = new EntranceGuardDoor();
				entranceGuardDoor.setDoorId(doorInfo.getId());
				entranceGuardDoor.setEquipmentId(doorInfo.getEquipmentInfo().getId());
				entranceGuardDoor.setRuleId(entranceGuardRule.getId());
				entranceGuardDoorService.insert(entranceGuardDoor);
				addDoorInfos.add(doorInfo);
			}
			newDoorInfoMap.put(entranceGuardRule.getId()+ "_" + idsArr[i],idsArr[i]);
		}

		for(Map.Entry<String, DoorInfo> entry : oldDoorInfoMap.entrySet()){
			if(!newDoorInfoMap.containsKey(entry.getKey())) {
				//删除门禁郁闷关系
				List<SearchFilter> searchFilters = Lists.newArrayList();
				searchFilters.add(new SearchFilter("ruleId",SearchFilter.Operator.EQ,entranceGuardRule.getId()));
				searchFilters.add(new SearchFilter("doorId",SearchFilter.Operator.EQ,entry.getValue().getId()));
				List<EntranceGuardDoor> entranceGuardDoors = entranceGuardDoorService.queryAll(searchFilters);
				for (EntranceGuardDoor entranceGuardDoor:entranceGuardDoors) {
					entranceGuardDoorService.delete(entranceGuardDoor.getId());
				}
				removeDoorInfos.add(entry.getValue());
			}
		}


		String strTip = "";
		//向设备中写入人员信息
		List<UserCard> userCards = entranceGardUserService.getUserAndCardInfoByRuleId(entranceGuardRule.getId());
		for (DoorInfo doorInfo:addDoorInfos ) {
    		//向设备中写入人员信息
			entranceGuardService.addDataToDoor(doorInfo, TableConstant.TABLE_USER, userCards);

			//向设备中写入时段
			//todo 根据权限获取时段信息,设置时段信息
			entranceGuardService.addDataToDoor(doorInfo, TableConstant.TABLE_TIMEZONE, entranceGuardRule.getTimeInfo().toString());
			//向设备中写入权限信息
			List<UserauthorizeDto> userauthorizeDtos = Lists.newArrayList();
			for (UserCard userCard : userCards) {
				UserauthorizeDto userauthorizeDto = new UserauthorizeDto();
				userauthorizeDto.setUserId(userCard.getUserInfo().getId());
				userauthorizeDto.setTimeInfoId(entranceGuardRule.getTimeInfo().getId());
				userauthorizeDto.setDoorId(Long.valueOf(doorInfo.getDoorNo()));
				userauthorizeDtos.add(userauthorizeDto);
			}
			entranceGuardService.addDataToDoor(doorInfo, TableConstant.USERAUTHORIZE, userauthorizeDtos);

		}
		//向设备中写入需要删除的人员信息
		for (DoorInfo doorInfo:removeDoorInfos ) {
			//向设备中删除人员信息
			entranceGuardService.removeDataFromDoor(doorInfo, TableConstant.TABLE_USER, userCards);

			//向设备中写入时段
			//todo 根据权限获取时段信息,删除时段信息
			entranceGuardService.removeDataFromDoor(doorInfo, TableConstant.TABLE_TIMEZONE, entranceGuardRule.getTimeInfo().toString());
			//向设备中写入权限信息
			List<UserauthorizeDto> userauthorizeDtos = Lists.newArrayList();
			for (UserCard userCard : userCards) {
				UserauthorizeDto userauthorizeDto = new UserauthorizeDto();
				userauthorizeDto.setUserId(userCard.getUserInfo().getId());
				userauthorizeDto.setTimeInfoId(entranceGuardRule.getTimeInfo().getId());
				userauthorizeDto.setDoorId(Long.valueOf(doorInfo.getDoorNo()));
				userauthorizeDtos.add(userauthorizeDto);
			}
			entranceGuardService.removeDataFromDoor(doorInfo, TableConstant.USERAUTHORIZE, userauthorizeDtos);
		}

        SetDataToDeviceTip setDataToDeviceTip = new SetDataToDeviceTip(200,"");

        return setDataToDeviceTip;
    }
}